// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#include "coin2/exchange/korbit/api_util/auth_key.h"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "coin2/base/time.h"
#include "coin2/exchange/base/api_util/api_signature.h"
#include "coin2/exchange/base/api_util/json_writer.h"

std::string KorbitBaseAuth::auth_token_ = "";
std::string KorbitBaseAuth::refresh_token_ = "";

std::vector<std::pair<std::string, std::string>> KorbitRestAuth::GetHeaderSet() const {
  std::vector<std::pair<std::string, std::string>> out;
  out.push_back(std::make_pair("Authorization", "Bearer " + auth_token_));
  out.push_back(std::make_pair("Content-Type", "application/x-www-form-urlencoded"));
  return out;
}

AsioHttpContext* KorbitRestAuth::CreateRequestByGetWithSignature(
    const std::string& address,
    UrlParamsBuilder* builder) {
  std::string query_string = builder->ComputeQueryString();
  std::string post_body = builder->ComputePostBody();
  CHECK(post_body.empty());
  std::string target;
  if (!query_string.empty()) {
    target = address + "?" + query_string;
  } else {
    target = address;
  }

  return AsioHttpContext::NewGet(host_, port_, bind_ip_, target, GetHeaderSet());
}

AsioHttpContext* KorbitRestAuth::CreateRequestByPostWithSignature(
    const std::string& address,
    UrlParamsBuilder* builder) {
  // auth
  if (builder->ComputePostBody().empty()) {
    builder->PutPost("client_id", key_.access_key());
    builder->PutPost("client_secret", key_.secret_key());
    if (refresh_token_.empty()) {
      builder->PutPost("grant_type", "client_credentials");
    } else {
      builder->PutPost("refresh_token", refresh_token_);
      builder->PutPost("grant_type", "refresh_token");
    }
    std::vector<std::pair<std::string, std::string>> header;
    header.push_back(std::make_pair("Content-Type", "application/x-www-form-urlencoded"));
    auto ahc = AsioHttpContext::NewPost(
        host_,
        port_,
        bind_ip_,
        address,
        header,
        builder->ComputePostBodyAsQueryString());
    ahc->keep_user_agent = true;
    return ahc;
  }
  std::string query_string = builder->ComputeQueryString();
  std::string post_body = builder->ComputePostBodyAsQueryString();
  std::string target = address;
  if (!query_string.empty()) {
    target += "?" + query_string;
  }
  auto ahc = AsioHttpContext::NewPost(host_, port_, bind_ip_, target, GetHeaderSet(), post_body);
  ahc->keep_user_agent = true;
  return ahc;
}
